//
//  File.swift
//  casdon_swiftUI
//
//  Created by casdon on 2025/4/24.
//

import Combine
import AuthenticationServices

struct AppleAuthResult {
    let userId: String
    let idToken: String
    let authCode: String
}
private var delegateStore = Set<AppleAuthDelegate>()
struct AppleAuthStep: LoginStep {
    struct InputData {} // 无需输入参数
    
    func execute(_ input: InputData) -> AnyPublisher<AppleAuthResult, Error> {
        Future { promise in
            let provider = ASAuthorizationAppleIDProvider()
            let request = provider.createRequest()
            request.requestedScopes = [.fullName, .email]

            let controller = ASAuthorizationController(authorizationRequests: [request])
            
            var delegate: AppleAuthDelegate? = nil // 先声明为 optional var
            delegate = AppleAuthDelegate { result in
                // 捕获 delegate 的弱引用，防止循环引用
                if let d = delegate {
                    delegateStore.remove(d)
                }
                switch result {
                case .success(let authResult):
                    promise(.success(authResult))
                case .failure(let error):
                    promise(.failure(error))
                }
            }
            if let delegate = delegate
            {
                delegateStore.insert(delegate)
            }
            
            controller.delegate = delegate
            controller.presentationContextProvider = delegate
            controller.performRequests()
        }
        .eraseToAnyPublisher()
    }
}

private class AppleAuthDelegate: NSObject, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
    private let completion: (Result<AppleAuthResult, Error>) -> Void

    init(completion: @escaping (Result<AppleAuthResult, Error>) -> Void) {
        self.completion = completion
    }

    func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential,
              let tokenData = credential.identityToken,
              let tokenString = String(data: tokenData, encoding: .utf8)
        else {
            completion(.failure(NSError(domain: "AppleLogin", code: -1, userInfo: [NSLocalizedDescriptionKey: "授权失败"])))
            return
        }
        if let authCode = credential.authorizationCode
        {
            let authCode = String(data: authCode, encoding: .utf8)
            let result = AppleAuthResult(userId: credential.user, idToken: tokenString, authCode: authCode ?? "")
            completion(.success(result))
            return
        }
        let result = AppleAuthResult(userId: credential.user, idToken: tokenString, authCode: "")
        completion(.success(result))
    }

    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
        completion(.failure(error))
    }

    func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
        UIApplication.shared.connectedScenes
            .compactMap { $0 as? UIWindowScene }
            .flatMap { $0.windows }
            .first { $0.isKeyWindow } ?? UIWindow()
    }
}

